﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using Microsoft.Ccr.Core;
using XcoAppSpaces.Core;

namespace test.XcoAppSpaces.Core
{
	#region Test Workers with Concurrent/Exclusive/Teardown
	class SinglePortWorker : Port<string>
	{
		[XcoConcurrent]
		public void ProcessString(string msg) { }
	}


	public class WorkerContract : PortSet<int, string, bool>
	{
		public AutoResetEvent are = new AutoResetEvent(false);
	}

	class MyWorker : WorkerContract
	{
		public int intMsg;
		public string strMsg;

		[XcoExclusive]
		public void ProcessInt(int msg)
		{
			this.intMsg = msg;
		}

		[XcoConcurrent]
		public void ProcessString(string msg)
		{
			this.strMsg = msg;
		}

		[XcoTeardown]
		public void ProcessBool(bool msg)
		{
			base.are.Set();
		}
	}

	class MyWorkerInvalid : WorkerContract
	{
		[XcoExclusive]
		public void ProcessInt(int msg)
		{
		}

		[XcoConcurrent]
		public string ProcessString(string msg) //invalid return type
		{
			return msg;
		}

		[XcoTeardown]
		public void ProcessBool(bool msg)
		{
		}
	}

	class MyWorkerInvalid2 : WorkerContract //missing message processor for type string
	{
		[XcoExclusive]
		public void ProcessInt(int msg)
		{
		}

		[XcoTeardown]
		public void ProcessBool(bool msg)
		{
		}
	}
	#endregion

	#region Test Iterative Worker with Extension
	class MyIterativeWorker : WorkerContract
	{
		public WorkerExt ext = new WorkerExt();
		public int intMsg;
		public Port<int> portForIterator = new Port<int>();

		[XcoConcurrent]
		public IEnumerator<ITask> ProcessInt(int msg)
		{
			for (int i = 0; i < msg; i++)
			{
				Console.WriteLine("Receiving from int port...");
				yield return portForIterator.Receive();
				this.intMsg = portForIterator;
			}
		}

		[XcoConcurrent]
		public void ProcessBool(bool msg)
		{
			Console.WriteLine("Bool received: " + msg);
			base.are.Set();
		}
	}
	#endregion

	#region Workers for Extension Testing
	public class ExtensionWorkerInvalidContract : PortSet<int, bool>
	{
	}
	class ExtensionWorkerInvalid : ExtensionWorkerInvalidContract
	{
		public WorkerExt2 ext = new WorkerExt2();

		[XcoConcurrent]
		public void ProcessBool(bool msg)
		{
		}
	}

	class ExtensionWorkerInvalid2 : ExtensionWorkerInvalidContract
	{
		[XcoWorkerExtension]
		public string invalidExtension = "test";

		[XcoConcurrent]
		public void ProcessBool(bool msg)
		{
		}
	}

	public class ExtensionWorkerValidContract : PortSet<string, bool>
	{
	}
	class ExtensionWorkerValid : ExtensionWorkerValidContract
	{
		public WorkerExt2 ext = new WorkerExt2();

		[XcoConcurrent]
		public void ProcessBool(bool msg)
		{
		}
	}

	public class ExtensionWorkerAttrOverwriteContract : PortSet<int, bool>
	{
	}
	class ExtensionWorkerAttrOverwrite : ExtensionWorkerAttrOverwriteContract
	{
		[XcoWorkerExtension(typeof(int))]
		public WorkerExt2 ext = new WorkerExt2();

		[XcoConcurrent]
		public void ProcessBool(bool msg)
		{
		}
	}

	class ExtensionWorkerAttrOverwrite2 : ExtensionWorkerAttrOverwriteContract
	{
		[XcoWorkerExtension(Optional = new Type[] { typeof(string) })]
		public WorkerExt2 ext = new WorkerExt2();

		[XcoConcurrent]
		public void ProcessBool(bool msg)
		{
		}
	}

	class ExtensionWorkerAttrOverwrite3 : ExtensionWorkerAttrOverwriteContract
	{
		[XcoWorkerExtension(Required = new Type[] { typeof(int) })]
		public WorkerExt2 ext = new WorkerExt2();

		[XcoConcurrent]
		public void ProcessBool(bool msg)
		{
		}
	}
	#endregion

	#region Worker Extensions
	[XcoWorkerExtension]
	class WorkerExt
	{
		public string strMsg;

		[XcoConcurrent]
		public void ProcessString(string msg)
		{
			Console.WriteLine("WorkerExtension: String received: " + msg);
			strMsg = msg;
		}
	}

	[XcoWorkerExtension(typeof(string))]
	class WorkerExt2
	{
		public string strMsg;
		public int intMsg;

		[XcoConcurrent]
		public void ProcessString(string msg)
		{
			Console.WriteLine("WorkerExtension: String received: " + msg);
			strMsg = msg;
		}

		[XcoConcurrent]
		public void ProcessInt(int msg)
		{
			Console.WriteLine("WorkerExtension: Int received: " + msg);
			intMsg = msg;
		}
	}
	#endregion
}
